import 'dart:async';

/// 等待执行工具类（单线程安全）
/// @author: sunlunchang
class AwaitTaskUtils {
  static const Duration defaultTimeout = Duration(milliseconds: 5000);

  final Map<TaskKey, _TaskContext> _taskContexts = {};

  /// 通知等待执行任务完成
  /// [key] 任务标识
  /// [result] 任务结果数据
  Future<void> notifyTaskCompletion<T>(TaskKey key, T result) {
    final context = _taskContexts.remove(key);
    if (context != null) {
      context.completer.complete(TaskResponse.success(result));
    }
    return Future.value();
  }

  /// 通知等待执行任务失败
  /// [key] 任务标识
  /// [error] 错误对象
  /// [stackTrace] 堆栈跟踪
  Future<void> notifyTaskFailure(
      TaskKey key,
      Object error,
      StackTrace stackTrace,
      ) {
    final context = _taskContexts.remove(key);
    if (context != null) {
      context.completer.completeError(error, stackTrace);
    }
    return Future.value();
  }

  /// 执行并等待任务完成
  /// [key] 任务标识
  /// [task] 要执行的任务函数
  /// [timeout] 超时时间，默认5秒
  Future<TaskResponse> executeAndWait({
    required TaskKey key,
    required FutureOr<void> Function() task,
    Duration timeout = defaultTimeout,
  }) async {
    final completer = Completer<TaskResponse>();
    final context = _TaskContext(completer);

    _taskContexts[key] = context;

    try {
      // 执行任务
      await task();

      // 设置超时处理
      final timer = Timer(timeout, () {
        if (_taskContexts.remove(key) != null) {
          completer.complete(TaskResponse.timeout());
        }
      });

      // 等待结果
      final response = await completer.future.whenComplete(() {
        timer.cancel();
      });

      return response;
    } catch (error, stackTrace) {
      _taskContexts.remove(key);
      return TaskResponse.failure(error, stackTrace);
    }
  }

  /// 清除所有等待中的任务
  Future<void> clearAll() {
    for (final context in _taskContexts.values) {
      context.completer.complete(TaskResponse.cancelled());
    }
    _taskContexts.clear();
    return Future.value();
  }
}

/// 任务上下文
class _TaskContext {
  final Completer<TaskResponse> completer;

  _TaskContext(this.completer);
}

/// 任务标识
class TaskKey {
  final Object key;

  TaskKey(this.key);

  @override
  bool operator ==(Object other) =>
          other is TaskKey &&
              runtimeType == other.runtimeType &&
              key == other.key;

  @override
  int get hashCode => key.hashCode;
}

/// 任务响应结果
class TaskResponse {
  final bool isSuccess;
  final bool isTimeout;
  final bool isCancelled;
  final dynamic data;
  final Object? error;
  final StackTrace? stackTrace;

  TaskResponse._({
    this.isSuccess = false,
    this.isTimeout = false,
    this.isCancelled = false,
    this.data,
    this.error,
    this.stackTrace,
  });

  factory TaskResponse.success(dynamic data) => TaskResponse._(
    isSuccess: true,
    data: data,
  );

  factory TaskResponse.timeout() => TaskResponse._(isTimeout: true);

  factory TaskResponse.cancelled() => TaskResponse._(isCancelled: true);

  factory TaskResponse.failure(Object error, StackTrace stackTrace) =>
      TaskResponse._(
        error: error,
        stackTrace: stackTrace,
      );
}